﻿using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Rhino.Mocks;
using StockholmsStad.Web.UI.Class.Controller;
using StockholmsStad.Web.UI.Class.Interfaces;
using StockholmsStad.Web.UI.Class.Model;
using StockholmsStad.Web.UI.Class.Utilities;
using StockholmsStad.Web.UI.UIServiceReference;

namespace StockholmsStad.Web.UI.Test
{
    /// <summary>
    ///This is a test class for OurRegistrationControllerTest and is intended
    ///to contain all OurRegistrationControllerTest Unit Tests
    ///</summary>
    [TestClass()]
    public class OurRegistrationControllerTest
    {
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }

        #region Additional test attributes

        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //

        #endregion

        /// <summary>
        ///A test for UpdateContactName
        ///</summary>
        [TestMethod()]
        public void UpdateContactNameTest()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            IRegistrationModel model = mocks.StrictMock<IRegistrationModel>();
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            // Expect
            Expect.Call(contactView.ContactPersonListIsFirstPerson()).Return(true);
            Expect.Call(model.Couple).Return(new Couple
                                                 {
                                                     Person1 =
                                                         new Person("Svenne", "Snorslev", null, true, "", true, null),
                                                 });
            Expect.Call(() => contactView.UpdateContactPersonName("Svenne", "Snorslev"));
            Expect.Call(() => contactView.UpdateContactPersonName(false));
            // Replay
            mocks.ReplayAll();
            target.UpdateContactName();
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for UpdateChangablePages. Utan kontaktperson
        ///</summary>
        [TestMethod()]
        public void UpdateChangablePagesTest()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            IRegistrationModel model = mocks.StrictMock<IRegistrationModel>();
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            // Objects
            Person person1 = new Person("Svenne", "Snorslev", null, true, "", true, null)
                                 {
                                     Email = "Svenne@fsdf.nu",
                                     Phonenumber = "12345"
                                 };
            Person person2 = new Person("Svea", "Snorslev", null, true, "", false, null);
            Ceremony ceremony = new Ceremony
                                    {CeremonyLanguage = "Svenska", CertificateLanguage = "Svenska", SpecialNeeds = null};
            ContactPerson contact = new ContactPerson
                                        {
                                            Email = person1.Email,
                                            FirstNames = person1.FirstNames,
                                            LastName = person1.LastName,
                                            Telephone = person1.Phonenumber,
                                        };
            // Expect
            Expect.Call(model.Couple).Return(new Couple
                                                 {
                                                     Person1 = person1,
                                                     Person2 = person2,
                                                     ContactPerson = null,
                                                     CoupleId = 42,
                                                 });
            Expect.Call(() => personsView.UpdatePersons(person1, person2));
            Delegates.Action<ContactPerson, Ceremony, bool> compareArguments = (contactTest, ceremonyTest, boolTest) =>
                                                                                   {
                                                                                       AssertAreEqual(contact,
                                                                                                      contactTest);
                                                                                       Assert.AreSame(ceremony,
                                                                                                      ceremonyTest);
                                                                                       Assert.IsTrue(boolTest);
                                                                                   };
            Expect.Call(model.Ceremony).Return(ceremony);
            Expect.Call(() => contactView.UpdateContactAndCeremony(contact, ceremony, true))
                .IgnoreArguments().Do(compareArguments);
            Expect.Call(() => contactView.UpdateContactPersonListName("Svenne Snorslev"));
            // Replay
            mocks.ReplayAll();
            target.UpdateChangablePages();
            mocks.VerifyAll();
        }

        private static void AssertAreEqual(ContactPerson contact, ContactPerson test)
        {
            Assert.AreEqual(contact.Email, test.Email);
            Assert.AreEqual(contact.FirstNames, test.FirstNames);
            Assert.AreEqual(contact.LastName, test.LastName);
            Assert.AreEqual(contact.Telephone, test.Telephone);
        }

        /// <summary>
        ///A test for UpdateChangablePages. Med kontaktperson
        ///</summary>
        [TestMethod()]
        public void UpdateChangablePagesTest2()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            IRegistrationModel model = mocks.StrictMock<IRegistrationModel>();
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            // Objects
            Person person1 = new Person("Svenne", "Snorslev", null, true, "", true, null);
            Person person2 = new Person("Svea", "Snorslev", null, true, "", false, null);
            ContactPerson contact = new ContactPerson
                                        {
                                            Email = "Pelle@fsdf.nu",
                                            FirstNames = "Pelle",
                                            LastName = "Snorslev",
                                            Telephone = "12345"
                                        };
            Couple couple = new Couple
                                {
                                    Person1 = person1,
                                    Person2 = person2,
                                    ContactPerson = contact,
                                    CoupleId = 42,
                                };
            Ceremony ceremony = new Ceremony
                                    {CeremonyLanguage = "Svenska", CertificateLanguage = "Svenska", SpecialNeeds = null};
            // Expect
            Expect.Call(model.Couple).Return(couple);
            Expect.Call(() => personsView.UpdatePersons(person1, person2));
            Expect.Call(model.Ceremony).Return(ceremony);
            Expect.Call(() => contactView.UpdateContactAndCeremony(contact, ceremony, false));
            Expect.Call(() => contactView.UpdateContactPersonListName("Svenne Snorslev"));
            // Replay
            mocks.ReplayAll();
            target.UpdateChangablePages();
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for SubmitRegistrationUpdate
        ///</summary>
        [TestMethod()]
        public void SubmitRegistrationUpdateTest()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            IRegistrationModel model = mocks.StrictMock<IRegistrationModel>();
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            // Object
            User user = new User();
            // Expect
            Expect.Call(loginModel.User).Return(user);
            Expect.Call(() => model.RegisterCouple(user));
            // Replay
            mocks.ReplayAll();
            target.SubmitRegistrationUpdate();
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for RegisterPersons
        ///</summary>
        [TestMethod()]
        public void RegisterPersonsTest()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            var session = new DictionarySessionAdapter(new Dictionary<string, object>());
            var model = new RegistrationModel(session, mocks.StrictMock<IServiceFacade>());
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            // Objects
            var person1 = new Person("Svenne", "Snorslev", null, true, "", true, null);
            var person2 = new Person("Svenne2", "Snorslev2", null, true, "", true, null);
            // Expect
            Expect.Call(() => contactView.UpdateContactPersonListName(person1.FirstNames + " " + person1.LastName));
            Expect.Call(contactView.ContactPersonListIsFirstPerson()).Return(true);
            Expect.Call(() => contactView.UpdateContactPersonName("Svenne", "Snorslev"));
            Expect.Call(() => contactView.UpdateContactPersonName(false));
            // Replay
            mocks.ReplayAll();
            target.RegisterPersons(person1, person2);
            Assert.AreEqual(model.Couple.Person1, person1);
            Assert.AreEqual(model.Couple.Person2, person2);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for RegisterContact. Contact is first person
        ///</summary>
        [TestMethod()]
        public void RegisterContactTest()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            IRegistrationModel model = mocks.StrictMock<IRegistrationModel>();
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            // Objects
            ContactPerson contact = new ContactPerson
                                        {
                                            Email = "Pelle@fsdf.nu",
                                            FirstNames = "Svenne",
                                            LastName = "Snorslev",
                                            Telephone = "12345"
                                        };
            Ceremony ceremony = new Ceremony
                                    {CeremonyLanguage = "Svenska", CertificateLanguage = "Svenska", SpecialNeeds = null};
            var person1 = new Person("Svenne", "Snorslev", null, true, "", true, null);
            var person2 = new Person("Svenne2", "Snorslev2", null, true, "", true, null);
            Couple couple = new Couple {Person1 = person1, Person2 = person2};
            // Expect
            Expect.Call(model.Couple).Return(couple);
            Expect.Call(model.Ceremony = ceremony);
            // Replay
            mocks.ReplayAll();
            target.RegisterContact(contact, ceremony, true);
            Assert.AreEqual(contact.Email, couple.Person1.Email);
            Assert.AreEqual(contact.Telephone, couple.Person1.Phonenumber);
            Assert.AreEqual(null, couple.ContactPerson);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for RegisterContact. Separate contact
        ///</summary>
        [TestMethod()]
        public void RegisterContactTest2()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            IRegistrationModel model = mocks.StrictMock<IRegistrationModel>();
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            // Objects
            ContactPerson contact = new ContactPerson
                                        {
                                            Email = "Pelle@fsdf.nu",
                                            FirstNames = "Pelle",
                                            LastName = "Snorslev",
                                            Telephone = "12345"
                                        };
            Ceremony ceremony = new Ceremony
                                    {CeremonyLanguage = "Svenska", CertificateLanguage = "Svenska", SpecialNeeds = null};
            var person1 = new Person("Svenne", "Snorslev", null, true, "", true, null);
            var person2 = new Person("Svenne2", "Snorslev2", null, true, "", true, null);
            Couple couple = new Couple {Person1 = person1, Person2 = person2};
            // Expect
            Expect.Call(model.Couple).Return(couple);
            Expect.Call(model.Ceremony = ceremony);
            // Replay
            mocks.ReplayAll();
            target.RegisterContact(contact, ceremony, false);
            Assert.AreEqual(null, couple.Person1.Email);
            Assert.AreEqual(null, couple.Person1.Phonenumber);
            Assert.AreEqual(contact, couple.ContactPerson);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for PageLoad
        ///</summary>
        [TestMethod()]
        public void PageLoadTest()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            IRegistrationModel model = mocks.StrictMock<IRegistrationModel>();
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            // Objects
            ContactPerson contact = new ContactPerson
                                        {
                                            Email = "Pelle@fsdf.nu",
                                            FirstNames = "Pelle",
                                            LastName = "Snorslev",
                                            Telephone = "12345"
                                        };
            Ceremony ceremony = new Ceremony
                                    {CeremonyLanguage = "Svenska", CertificateLanguage = "Svenska", SpecialNeeds = null};
            var person1 = new Person("Svenne", "Snorslev", null, true, "", true, null);
            var person2 = new Person("Svenne2", "Snorslev2", null, true, "", true, null);
            Couple couple = new Couple {Person1 = person1, Person2 = person2, ContactPerson = contact};
            User user = new User();
            // Expect
            Expect.Call(loginModel.User).Return(user);
            Expect.Call(() => model.UpdateCoupleFromServer(user));
            Expect.Call(() => model.UpdateCeremonyFromServer(user));
            Expect.Call(model.Couple).Return(couple);
            Expect.Call(summaryView.Person1 = person1);
            Expect.Call(summaryView.Person2 = person2);
            Expect.Call(summaryView.Contact = contact);
            Expect.Call(model.Ceremony).Return(ceremony);
            Expect.Call(summaryView.Ceremony = ceremony);
            // Replay
            mocks.ReplayAll();
            target.PageLoad();
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for GetWeddingCertificateLanguages
        ///</summary>
        [TestMethod()]
        public void GetWeddingCertificateLanguagesTest()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            IRegistrationModel model = mocks.StrictMock<IRegistrationModel>();
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            // Objects
            IEnumerable<string> languages = new List<string>
                                                {
                                                    "Spanska",
                                                    "Transpiranto",
                                                };
            // Expect
            Expect.Call(model.WeddingCertificateLanguages).Return(languages);
            // Replay
            mocks.ReplayAll();
            IEnumerable<string> actual = target.GetWeddingCertificateLanguages();
            Assert.AreEqual(languages, actual);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for GetCeremonySpecialNeeds
        ///</summary>
        [TestMethod()]
        public void GetCeremonySpecialNeedsTest()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            IRegistrationModel model = mocks.StrictMock<IRegistrationModel>();
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            // Objects
            IEnumerable<string> list = new List<string>
                                           {
                                               "Rullstol",
                                               "Kryckor",
                                           };
            // Expect
            Expect.Call(model.CeremonySpecialNeeds).Return(list);
            // Replay
            mocks.ReplayAll();
            IEnumerable<string> actual = target.GetCeremonySpecialNeeds();
            Assert.AreEqual(list, actual);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for GetCeremonyLanguages
        ///</summary>
        [TestMethod()]
        public void GetCeremonyLanguagesTest()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            IRegistrationModel model = mocks.StrictMock<IRegistrationModel>();
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            // Objects
            IEnumerable<string> languages = new List<string>
                                                {
                                                    "Spanska",
                                                    "Transpiranto",
                                                };
            // Expect
            Expect.Call(model.CeremonyLanguages).Return(languages);
            // Replay
            mocks.ReplayAll();
            IEnumerable<string> actual = target.GetCeremonyLanguages();
            Assert.AreEqual(languages, actual);
            mocks.VerifyAll();
        }

        /// <summary>
        ///A test for OurRegistrationController Constructor
        ///</summary>
        [TestMethod()]
        public void OurRegistrationControllerConstructorTest()
        {
            var mocks = new MockRepository();
            var contactView = mocks.StrictMock<IRegistration2_Contact>();
            var summaryView = mocks.StrictMock<IRegistration3_Summary>();
            var personsView = mocks.StrictMock<IRegistration1_Persons>();
            IRegistrationModel model = mocks.StrictMock<IRegistrationModel>();
            ILoginModel loginModel = mocks.StrictMock<ILoginModel>();
            var target = new OurRegistrationController(model, loginModel, summaryView, personsView, contactView);
            Assert.IsNotNull(target);
        }
    }
}